

#import "KLUserDefaults.h"
#import "ReactiveCocoa.h"

// ----------------------------------
// Source code
// ----------------------------------

#pragma mark -

@implementation KLUserDefaults

KLDEF_SINGLETON( KLUserDefaults )

- (RACSignal *)hasObjectForKey:(id)key{
    id value = [[NSUserDefaults standardUserDefaults] objectForKey:key];
    return [RACSignal return:value ? @YES : @NO];
}

- (RACSignal*)clearAll{
    return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        [NSUserDefaults resetStandardUserDefaults];
        
        [subscriber sendNext:@(YES)];
        [subscriber sendCompleted];
        return nil;
    }];
}

- (RACSignal*)clearExpired:(NSDate*)date{
    
    return [RACSignal return:@(YES)];
}

- (RACSignal*)objectForKey:(NSString*)key{
    NSParameterAssert(key);
    id value = [[NSUserDefaults standardUserDefaults] objectForKey:key];
    return [RACSignal return:value];
}
- (RACSignal*)setObject:(id <NSCoding>)object forKey:(NSString *)key{
    NSParameterAssert(object);
    NSParameterAssert(key);

    return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        
        [[NSUserDefaults standardUserDefaults] setObject:object forKey:key];
        [[NSUserDefaults standardUserDefaults] synchronize];
    
        [subscriber sendNext:@(YES)];
        [subscriber sendCompleted];
        return nil;
    }];
    
}
- (RACSignal*)removeObjectForKey:(NSString*)key{
    NSParameterAssert(key);
    
    return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        
        [[NSUserDefaults standardUserDefaults] removeObjectForKey:key];
        [[NSUserDefaults standardUserDefaults] synchronize];
        
        [subscriber sendNext:@(YES)];
        [subscriber sendCompleted];
        return nil;
    }];
    
}

- (RACSignal*)objectForKeyedSubscript:(id)key
{
    return [self objectForKey:key];
}

- (RACSignal*)setObject:(id)obj forKeyedSubscript:(id)key
{
    if ( obj )
    {
        return [self setObject:obj forKey:key];
    }
    else
    {
        return [self removeObjectForKey:key];
    }
}


@end

